#include <iostream>
#include <stdio.h>
#include <exception>
#include "list.h"

#define SYNTAX_ERROR 1

char token=0;

//function declarations
void readNext();
ListElement *lst();
Sequence *seq(Sequence *seqPtr);
ListElement *elmnt();

//reads next character and puts into global var token
void readNext()
{
	token = getchar();
}
//checks if the last read char is what it is expected to be
//throws an syntax error exception if check fails
void match(char c) throw(int)
{
	if(token!=c)
		throw(SYNTAX_ERROR);
}
//reads the number from input
//throws exception if the current position of the input is not a number
int matchNumber()
{
	if(token<48 || token >57)
		throw SYNTAX_ERROR;

	int number = token - 48;
	readNext();
	while(token>=48 && token <=57)
	{
		number = number*10 + token-48;
		readNext();
	}
	return number;
}

//list function of the grammar
ListElement *lst()
{
	List *lst = new List();

	match('(');

	readNext();
	if(token!=')')
	{
		Sequence *seqPtr = new Sequence();
		lst->insertSequence(seq(seqPtr));
	}

	match(')');
	readNext();
	return lst;
}

//sequence function of the grammar
Sequence *seq(Sequence *seqPtr)
{
	seqPtr->insertListElement(elmnt());
	if(token == ',')
	{
		match(',');
		readNext();
		seqPtr = seq(seqPtr);
	}
	return seqPtr;
}

//list element function of the grammar
ListElement *elmnt()
{
	if(token == '(')
		return lst();
	else if(token>=48 && token <=57)
		return new Number(matchNumber());
	else
		throw SYNTAX_ERROR;
}

//main function to test
int main()
{
	int a;
	ListElement *ptr;
	readNext();
	try
	{
		ptr = lst();
		match('$');
	}
	catch(int error)
	{
		if(error == SYNTAX_ERROR)
			std::cout<<"Syntax Error"<<std::endl;
		return -1;
	}

	//if the input is a valid program, stored data structure is printed.
	ptr->print(FORWARD);
	std::cout<<std::endl;
}